/*
 *  Copyright (c) 2022 ZhuHai Jieli Technology Co.,Ltd.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

/*********************************************************************************************
    *   Filename        : misc_hw.c

    *   Description     :

    *   Author          : Bingquan

    *   Email           : bingquan_cai@zh-jieli.com

    *   Last modifiled  : 2018-12-05 19:56

    *   Copyright:(c)JIELI  2011-2017  @ , All Rights Reserved.
*********************************************************************************************/
#include "asm/cpu.h"
#include "asm/power/p33.h"
#include "asm/power_interface.h"
#include "power_wakeup.h"
#include "asm/hwi.h"

#define LOG_TAG_CONST   P33_MISC
#define LOG_TAG         "[P33 MISC]"

#define LOG_ERROR_ENABLE
#define LOG_INFO_ENABLE
#define LOG_DUMP_ENABLE
#include "debug.h"

#define IRQ_FUNCTION_PROTOTYPE(idx, hdl) \
    __attribute__((interrupt("")))

#define IRQ_REGISTER(idx, hdl, prio) \
    request_irq(idx, prio, hdl, 0)
/*
 *
 * Watchdog hardware APIs
 *
 */

#define WD_1MS            0x00
#define WD_2MS            0x01
#define WD_4MS            0x02
#define WD_8MS            0x03
#define WD_16MS            0x04
#define WD_32MS            0x05
#define WD_64MS            0x06
#define WD_128MS        0x07
#define WD_256MS        0x08
#define WD_512MS        0x09
#define WD_1S            0x0A
#define WD_2S            0x0B
#define WD_4S            0x0C
#define WD_8S            0x0D
#define WD_16S            0x0E
#define WD_32S            0x0F

void watchdog_close(void)
{
    p33_and_1byte(P3_WDT_CON, ~BIT(4));
}

static void __watchdog_isr(void);
void watchdog_init(u8 config)
{
    P33_CON_SET(P3_WDT_CON, 4, 2, 0b01);

    P33_CON_SET(P3_WDT_CON, 0, 4, 0b1100);
    IRQ_REGISTER(IRQ_RTC_WDT_IDX, __watchdog_isr, 3);
}

void watchdog_clear(void)
{
    p33_or_1byte(P3_WDT_CON, BIT(6));
}

IRQ_FUNCTION_PROTOTYPE(IRQ_WD_IDX, __watchdog_isr) static void __watchdog_isr(void)
{
    u32 tmp;
    u32 rets, reti;

    __asm__ volatile("%0 = rets" : "=r"(rets));
    __asm__ volatile("%0 = reti" : "=r"(reti));

    log_error("\r\n\r\n---------------------------watchdog---------------------\r\n\r\n");
    log_error("RETS = %08x \r\n", rets);
    log_error("RETI = %08x \r\n", reti);

    __asm__ volatile("%0 = sp" : "=r"(tmp));
    log_error("SP = %08x \r\n", tmp);
    __asm__ volatile("%0 = usp" : "=r"(tmp));
    log_error("USP = %08x \r\n", tmp);
    __asm__ volatile("%0 = ssp" : "=r"(tmp));
    log_error("SSP = %08x \r\n", tmp);

    while (1) {
    }
}
/* ----------------------------------------------------------- */
